﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Windows;
using System.Windows.Data;
using SoftSource.Common;
using SoftSource.Timecard.ViewModelInterfaces;
using SoftSource.Timecard.Web.Data;

namespace SoftSource.Timecard.ViewModels
{
    public sealed class UserProjectEditorViewModel : IUserProjectEditorViewModel
    {
        public UserProjectEditorViewModel()
        {
            this.ProjectMembers = new ObservableCollection<ProjectMember>();
        }

        #region IProjectMemberEditorViewModelConsume Members

        private PagedCollectionView sourceProjects;
        public PagedCollectionView SourceProjects
        {
            get { return this.sourceProjects; }
            private set
            {
                this.sourceProjects = value;
                this.SourceProjects.SortDescriptions.Add(new SortDescription(
                    ObjectReflection.GetPropertyName<ProjectSummary>(p => p.Name),
                    ListSortDirection.Ascending));
                this.sourceProjects.MoveCurrentToFirst();
                this.PropertyChanged.Notify(() => this.SourceProjects);
            }
        }

        private PagedCollectionView userProjects;
        public PagedCollectionView UserProjects
        {
            get { return this.userProjects; }
            private set
            {
                this.userProjects = value;
                this.userProjects.SortDescriptions.Add(new SortDescription(
                    ObjectReflection.GetPropertyName<ProjectSummary>(p => p.Name),
                    ListSortDirection.Ascending));
                this.userProjects.MoveCurrentToFirst();
                this.PropertyChanged.Notify(() => this.UserProjects);
            }
        }

        public Action<object> AddToUser
        {
            get { return obj => this.AddToUserService(obj as ProjectSummary); }
        }

        public Action<object> RemoveFromUser
        {
            get { return obj => this.RemoveFromUserService(obj as ProjectMember); }
        }

        public Func<ProjectSummary, Action, UIElement> CreateProjectMemberEditor { get; set; }
        public Action Completed { get; set; }

        public IObservable<Unit> Load { get; set; }

        #endregion

        #region IProjectMemberEditorViewModelService Members

        private IEnumerable<ProjectMember> projectMembers;
        public IEnumerable<ProjectMember> ProjectMembers 
        {
            get { return this.projectMembers; }
            set
            {
                this.projectMembers = value;
                this.RefreshProjectMembers();
            }
        }

        private IEnumerable<ProjectSummary> projectSource;
        public IEnumerable<ProjectSummary> ProjectSource
        {
            get { return this.projectSource; }
            set
            {
                this.projectSource = value;                
                this.RefreshProjectMembers();
            }
        }

        private IObservable<Unit> sourceUpdated;
        public IObservable<Unit> SourceUpdated
        {
            get { return this.sourceUpdated; }
            set
            {
                this.sourceUpdated = value;
                this.sourceUpdated.Subscribe(unit => this.RefreshProjectMembers());
            }
        }

        public Action<ProjectSummary> AddToUserService { get; set; }
        public Action<ProjectMember> RemoveFromUserService { get; set; }

        #endregion

        #region Methods
        public void RefreshProjectMembers()
        {
            if (this.ProjectSource != null && this.ProjectMembers != null)
            {
                var filteredProjects = this.ProjectSource
                    .Where(project => project.StatusID == ProjectStatus.Active)
                    .Where(project => this.ProjectMembers.Any(p => p.ProjectID == project.ProjectID) == false);
                this.SourceProjects = new PagedCollectionView(filteredProjects);
                
                var members = from pm in this.ProjectMembers
                              join ps in this.ProjectSource on pm.ProjectID equals ps.ProjectID
                              select ps;

                this.UserProjects = new PagedCollectionView(members);
            }
        }
        #endregion Methods

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion

        ~UserProjectEditorViewModel()
        {
            this.Dispose();
        }
    }
}
